<html>
<head>
<title>firstworks   Programming with Rudiments using the sharedmemory class</title>
<link href="../css/styles.css" rel="stylesheet">
</head>
<body>

<span class="heading">Using the sharedmemory class</span><br><br>

<p>Shared memory allows seperate processes to access a common block of memory.  The <a href="../classes/html/classsharedmemory.html">sharedmemory class</a> provides methods for creating and accessing shared memory.</p>

<p>This program creates a shared memory segment, copies some data into it, then goes to sleep, giving another program time to access the segment.</p>

<blockquote class="code">

<script type='text/javascript'>
<!--

-->
</script>
<font face="monospace">
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/sharedmemory.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/charstring.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/permissions.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/file.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/error.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/snooze.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/process.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/stdio.h&gt;</font><br>
<br>
<font color="#2e8b57"><b>int</b></font>&nbsp;main(<font color="#2e8b57"><b>int</b></font>&nbsp;argc,&nbsp;<font color="#2e8b57"><b>const</b></font>&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;**argv) {<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// create a file called &quot;shm&quot;</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file::createFile(<font color="#ff00ff">&quot;shm&quot;</font>,permissions::evalPermString(<font color="#ff00ff">&quot;rw-------&quot;</font>));<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// create a 128 byte shared memory segment, keyed to the file &quot;shm&quot;</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sharedmemory&nbsp;&nbsp;&nbsp;&nbsp;shm;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!shm.create(file::generateKey(<font color="#ff00ff">&quot;shm&quot;</font>,<font color="#ff00ff">1</font>),<font color="#ff00ff">128</font>,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;permissions::evalPermString(<font color="#ff00ff">&quot;rw-------&quot;</font>))) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;error:&nbsp;</font><font color="#6a5acd">%s</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>,error::getErrorString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process::exit(<font color="#ff00ff">1</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// write a string into the shared memory</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;&nbsp;&nbsp;&nbsp;*shmptr=(<font color="#2e8b57"><b>char</b></font>&nbsp;*)shm.getPointer();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charstring::copy(shmptr,<font color="#ff00ff">&quot;This string is in shared memory.&quot;</font>);<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// sleep for 10 seconds, giving another process some time to access</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// the shared memory...</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;snooze::macrosnooze(<font color="#ff00ff">10</font>);<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// remove the file &quot;shm&quot;</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file::remove(<font color="#ff00ff">&quot;shm&quot;</font>);<br>
}<br>
</font>
<!-- vim: set foldmethod=manual : -->
</blockquote>

<p>This program reads the data from shared memory.</p>

<blockquote class="code">

<script type='text/javascript'>
<!--

-->
</script>
<font face="monospace">
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/sharedmemory.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/permissions.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/file.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/error.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/process.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/stdio.h&gt;</font><br>
<br>
<font color="#2e8b57"><b>int</b></font>&nbsp;main(<font color="#2e8b57"><b>int</b></font>&nbsp;argc,&nbsp;<font color="#2e8b57"><b>const</b></font>&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;**argv) {<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// attach to the shared memory segment keyed to the file &quot;shm&quot;</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sharedmemory&nbsp;&nbsp;&nbsp;&nbsp;shm;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!shm.attach(file::generateKey(<font color="#ff00ff">&quot;shm&quot;</font>,<font color="#ff00ff">1</font>),<font color="#ff00ff">128</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;error:&nbsp;</font><font color="#6a5acd">%s</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>,error::getErrorString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process::exit(<font color="#ff00ff">1</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// display the data contained in the shared memory segment</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;</font><font color="#6a5acd">%s</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>,(<font color="#2e8b57"><b>char</b></font>&nbsp;*)shm.getPointer());<br>
}<br>
</font>
<!-- vim: set foldmethod=manual : -->
</blockquote>

<p>Note that on unix-like systems, the first program should not be killed.  Shared memory segments are persistent in the kernel and remain unless specifically removed.  The sharedmemory class will remove the shared memory segment that it created when the instance of the class is destroyed, but if the first process is killed then the shared memory segment will persist and subsequent attempts to run the program will fail with a cryptic error like "File exists" or similar.</p>

<p>If this happens, most unix-like systems provide utilites for examining and cleaning up shared memory segments.</p>

<p>Running <i>ipcs -m</i> allows you to examine shared memory segments.  It ought to return something like:</p>

<blockquote>
<pre>
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x010114e8 190021641  dmuse      600        128        1
</pre>
</blockquote>

<p>The shmid can then be used with the <i>ipcrm</i> utility to remove the shared memory segment.  For example: <i>ipcrm -m 190021641</i></p>

<p>None of this is an issue on Windows systems.</p>

</body>
</html>
